package com.study.Caro;

import java.util.concurrent.locks.ReentrantLock;

import com.study.GameService.NetConnection.GameService;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class Screen extends SurfaceView implements SurfaceHolder.Callback{
	
	/*=====================attribute========================*/
	public static int SCREEN_SIZE_X = 11;
	public static int SCREEN_SIZE_Y = 11;

	private Caro mContext;
	public Brain brain; //matran luu vi tri 
	
	public float pre_X=0,pre_Y=0;	// vi tri touch len man hinh
	public int X_idx, Y_idx;
	
	private Bitmap O_simple; //ky tu X
	private Bitmap X_simple; //ky tu Y
	private Bitmap CHESSBOARD;	 //ban co
	
	private float X_datum;	 // goc toa do theo truc X cua ban co (pixel)
	private float Y_datum; 	 // goc toa do theo truc Y cua ban co (pixel)
	private float unit;		 // kich thuoc 1 o ban co (pixel)
	private float scale;	 // ty le giua hinh ve ra man hinh voi kich thuoc that
	private float correct_factor; // he so dich chinh de ve quan co
	private Matrix matrix;	 // matrix dug de scale resource truoc khi ve ra screen
	
	private SurfaceHolder surfaceholder;
	private Paint cPaint;
	
	GameService game = null;
	
	/*======================================================*/
	
	/*=======================method=========================*/
	
	public Screen(Context context){
		super(context);
		mContext = (Caro)context;
		getHolder().addCallback(this);
	}
	public Screen(Context context, AttributeSet attrs){
		super(context, attrs);
		mContext = (Caro)context;
		getHolder().addCallback(this);
	}
	
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		// TODO Auto-generated method stub
	}
	public void surfaceCreated(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		int CHESSBOARD_WIDTH;
		int CHESS_MAN_SIZE;
		
		O_simple = BitmapFactory.decodeResource(getResources(), R.drawable.o);
		X_simple = BitmapFactory.decodeResource(getResources(), R.drawable.x);
		CHESSBOARD = BitmapFactory.decodeResource(getResources(), R.drawable.base);
		
		CHESSBOARD_WIDTH = CHESSBOARD.getWidth();
		CHESS_MAN_SIZE = O_simple.getWidth();
		
		
		O_simple = Bitmap.createBitmap(O_simple, 0, 0, O_simple.getWidth(), O_simple.getHeight(), matrix, false);
		X_simple = Bitmap.createBitmap(X_simple, 0, 0, X_simple.getWidth(), X_simple.getHeight(), matrix, false);
		CHESSBOARD = Bitmap.createBitmap(CHESSBOARD, 0, 0, CHESSBOARD.getWidth(), CHESSBOARD.getHeight(), matrix, false);
		
		brain = Brain.GetInstance();	// KHOI TAO MA TRAN VI TRI
		
		surfaceholder = holder;
		cPaint = new Paint();

		scale = Screen.this.getWidth()/CHESSBOARD_WIDTH;
		unit = (CHESSBOARD_WIDTH/(SCREEN_SIZE_X+1))*scale;
		correct_factor = (CHESSBOARD_WIDTH/(SCREEN_SIZE_X+1)-CHESS_MAN_SIZE)/2;
		X_datum = 0;
		Y_datum = (Screen.this.getHeight()-Screen.this.getWidth())/2;
		matrix = new Matrix();
		matrix.postScale(scale, scale);

		
		Canvas canvas = surfaceholder.lockCanvas();
		canvas.drawBitmap(CHESSBOARD,X_datum,Y_datum,cPaint);	// VE BAN CO
		surfaceholder.unlockCanvasAndPost(canvas);
	}
	public void surfaceDestroyed(SurfaceHolder holder) {
		// TODO Auto-generated method stub
	}
	
	
	public void update_screen() {
		
		while(true)
		{
			if(!surfaceholder.getSurface().isValid()) continue;
			else break;
		}
		
		// Update text items:
		
		Canvas canvas = surfaceholder.lockCanvas();
		
		canvas.drawBitmap(CHESSBOARD,X_datum,Y_datum,cPaint);			// VE BAN CO
		
		for(int i=0;i<=SCREEN_SIZE_Y;i=i+1)						// VE QUAN CO
		{	
			for(int j=0;j<=SCREEN_SIZE_X;j=j+1)
			{	
				switch(brain.getValue(j, i))
				{
					case 1: // ky tu X
						canvas.drawBitmap(X_simple,(float)(X_datum+j*unit+correct_factor*scale),(float)(Y_datum+i*unit+correct_factor*scale),cPaint);
						break;
					case 2: // ky tu O
						canvas.drawBitmap(O_simple,(float)(X_datum+j*unit+correct_factor*scale),(float)(Y_datum+i*unit+correct_factor*scale),cPaint);
						break;
					default: break;
				}						
			}			
		}

		surfaceholder.unlockCanvasAndPost(canvas);
		
	}
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		
		switch(event.getAction())
		{
		case MotionEvent.ACTION_POINTER_DOWN:
		case MotionEvent.ACTION_DOWN:
			pre_X = event.getX();
			pre_Y = event.getY();
			X_idx = (int)((event.getX()-X_datum)/unit);
			Y_idx = (int)((event.getY()-Y_datum)/unit);
			return true;
		case MotionEvent.ACTION_MOVE:
			return true;
		case MotionEvent.ACTION_UP:
			
			if(Math.abs(event.getX() - pre_X) < 10 &&	Math.abs(event.getY() - pre_Y) < 10 
					&& X_idx >=0 && Y_idx >=0) // user clicked
			{
				// Get lock to change gameToken state
				final ReentrantLock lock = brain.GetLock();
				lock.lock();
				if (brain.Processing(X_idx, Y_idx) == Brain.POINT_VALID) { // valid action
					brain.UpdateState(X_idx, Y_idx, true);
					mContext.UpdateScreen(X_idx, Y_idx);
					/*-----------------UPDATE LEN SCREEN------------------*/
					update_screen();
					
					/*------------------------------SEND MSG--------------------------------*/
					Message msg = Message.obtain();
					String format = "GAME:%d-%d";
					String message = String.format(format, X_idx, Y_idx);
					msg.obj = message;
					GameService.SendData(msg);
				}
				// Unlock gameToken state
				lock.unlock();
			}
			
			return true;
			
		default: 
			break;
		}
		return super.onTouchEvent(event);
	}
	
	/*======================================================*/
}